/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：Connection.js<br>
 * 日期：2016年11月9日<br>
 * 作者: 王志远<br>
 * 功能：连接图元<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window,"Rainier.UI.V2");

/**
 * 类型名称：Rainier.UI.V2.Rainier.UI.V2.Connection<br>
 * 类型功能：元器件基类<br>
 */
Rainier.UI.V2.Connection = draw2d.Connection.extend({
	
	NAME : "Rainier.UI.V2.Connection",
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection<br>
	 * 函数功能：构造函数<br>
	 * 异常信息：无<br>
	 */
	init : function(attr, setter, getter){
		this._super(attr, setter, getter);
		this.setCoronaWidth(2);
		var _this = this;
		
		//Source或Target移动事件侦听器
		this.moveListener = function(figure){
			//执行移动操作
			if(figure===_this.sourcePort){
				_this.setStartPoint(_this.sourcePort.getAbsoluteX(), _this.sourcePort.getAbsoluteY());
	        }else if(figure===_this.targetPort){
	        	_this.setEndPoint(_this.targetPort.getAbsoluteX(), _this.targetPort.getAbsoluteY());
	        }
			_this.saveOldSegments();
			//更新子图元
			//var start = new Date().getTime();
			_this.refreshChild();
	    	//var end = new Date().getTime();
	    	
	    	//console.log("add model cost:" + (end - start));
	    };
	    
	    //source或target拖拽开始事件侦听器
	    this.dragStartListener = function(figure){
			//复制当前Segments保存为历史记录
	    	_this.saveOldSegments();
	    };
	    
	    //source或target拖拽结束事件侦听器
	    this.dragEndListener = function(figure){
			var children = _this.getChildren();
			children.each(function(i,figure){
				if(figure instanceof draw2d.shape.basic.Label){
					return true;
				}
				figure.clearAllAttachedSegment();
			});
	    	_this.refreshChild();
	    };
	    
	    //侦听顶点变化事件
	    this.on("change:vertices",function(){
	    	_this.refreshChild();
	    });
	    
	    //老线段
	    this.oldSegments = new draw2d.util.ArrayList();
	    
	    this.nodeLabelFigure = null;

	    this.targetDecorator = new draw2d.decoration.connection.ArrowDecorator();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.DeviceBoxFigure.setSymbolLabelFigure<br>
	 * 函数功能：设置Label<br>
	 * 参数输入：<br>
	 * property:属性对象<br>
	 * sLocator:定位器构造函数<br>
	 * x:Number<br>
	 * y:Number<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	setNodeLabelFigure : function(property){
		var locator = new Rainier.UI.V2.ConnectNodeLocator();
		property.stroke = 0;
		this.nodeLabelFigure = new Rainier.UI.V2.ConnectNodeFigure(property,locator);
		this.add(this.nodeLabelFigure,locator);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.DeviceBoxFigure.showLabel<br>
	 * 函数功能：显示标签<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	showNodeLabel : function(){
		if(this.nodeLabelFigure){
			this.nodeLabelFigure.setVisible(true);
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.DeviceBoxFigure.unshowLabel<br>
	 * 函数功能：隐藏标签<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	unshowNodeLabel : function(){
		if(this.nodeLabelFigure){
			this.nodeLabelFigure.setVisible(false);
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.DeviceBoxFigure.changeNodeLabel<br>
	 * 函数功能：修改标签<br>
	 * 参数输入：label:新标签名<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	changeNodeLabel : function(label){
		if(this.nodeLabelFigure){
			if(this.canvas){
				var visible = !this.canvas.context.menuItemUsedInfo.jointPortUsed;
				this.nodeLabelFigure.setVisible(visible);
			}
			this.nodeLabelFigure.setText(label);		
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.addVertex<br>
	 * 函数功能：override super method<br>
	 */
	addVertex:function(x, y){
		this.saveOldSegments();
		this._super(x,y);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.setVertex<br>
	 * 函数功能：override super method<br>
	 */
	setVertex : function(index, x, y){
		this.saveOldSegments();
		this._super(index,x,y);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.insertVertexAt<br>
	 * 函数功能：override super method<br>
	 */
	insertVertexAt:function(index, x, y){
		this.saveOldSegments();
		this._super(index,x,y);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.removeVertexAt<br>
	 * 函数功能：override super method<br>
	 */
	removeVertexAt:function(index){
		this.saveOldSegments();
		this._super(index);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.reconnect<br>
	 * 函数功能：override super method<br>
	 */
	reconnect : function(){
		this._super();
		if(this.sourcePort){
			this.sourcePort.parent.on("dragstart",this.dragStartListener);
			this.sourcePort.parent.on("dragend"  ,this.dragEndListener);
		}
		if(this.targetPort){
			this.targetPort.parent.on("dragstart",this.dragStartListener);
			this.targetPort.parent.on("dragend"  ,this.dragEndListener);
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.setSource<br>
	 * 函数功能：override super method<br>
	 */
	setSource : function( port){
		this._super(port);
		this.sourcePort.parent.on("dragstart",this.dragStartListener);
		this.sourcePort.parent.on("dragend"  ,this.dragEndListener);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.setTarget<br>
	 * 函数功能：override super method<br>
	 */
	setTarget : function( port){
		this._super(port);
		this.targetPort.parent.on("dragstart",this.dragStartListener);
		this.targetPort.parent.on("dragend"  ,this.dragEndListener);
	},
		
	/**
	 * 函数名称：Rainier.UI.V2.Connection.onDragStart<br>
	 * 函数功能：override super method<br>
	 */
	onDragStart: function(x, y, shiftKey, ctrlKey, isFaked ){
		//复制当前Segments保存为历史记录
		this.saveOldSegments();
		//开始拖拽操作
		this._super(x, y, shiftKey, ctrlKey, isFaked);
	},

	/**
	 * 函数名称：Rainier.UI.V2.Connection.onDrag<br>
	 * 函数功能：override super method<br>
	 */
	onDrag : function( dx, dy, dx2, dy2){
		this._super(dx, dy, dx2, dy2);
		this.refreshChild();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.onDragEnd<br>
	 * 函数功能：override super method<br>
	 */
	onDragEnd : function( x, y, shiftKey, ctrlKey){
		this._super(x, y, shiftKey, ctrlKey);
		var children = this.getChildren();
		children.each(function(i,figure){
			if(figure instanceof draw2d.shape.basic.Label){
				return true;
			}
			figure.clearAllAttachedSegment();
		});
		this.refreshChild();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.add<br>
	 * 函数功能：override super method<br>
	 */
	add : function(figure,locator){
		this._super(figure,locator);
		this.refreshChild();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.saveOldSegments<br>
	 * 函数功能：保存历史线段表<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	saveOldSegments : function(){
		//复制当前Segments保存为历史记录
		var _this = this;
		this.oldSegments = new draw2d.util.ArrayList();
		var segments = this.getSegments();
		segments.each(function(i,seg){
			var start  = new draw2d.geo.Point(seg.start.x,seg.start.y);
			var end    = new draw2d.geo.Point(seg.end.x,seg.end.y);
			var newseg = {index:i,start:start,end:end};
			_this.oldSegments.add(newseg);
		});
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.saveOldSegments<br>
	 * 函数功能：保存历史线段表<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	saveOldSegmentsByVertices : function(vertices){
		//复制当前Segments保存为历史记录
		var _this = this;
		this.oldSegments = new draw2d.util.ArrayList();
		for(var i = 0;i<vertices.getSize() - 1;i++){
			var start  = new draw2d.geo.Point(vertices.get(i).x,vertices.get(i).y);
			var end    = new draw2d.geo.Point(vertices.get(i+1).x,vertices.get(i+1).y);
			var newseg = {index:i,start:start,end:end};
			_this.oldSegments.add(newseg);
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.getOldSegments<br>
	 * 函数功能：获取旧的线段列表<br>
	 * 函数返回：draw2d.util.ArrayList<br>
	 * 异常信息：无<br>
	 */
	getOldSegments : function(){
		return this.oldSegments;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.Connection.refreshChild<br>
	 * 函数功能：刷新子图元关联性<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	refreshChild : function(){
		var children 	= this.getChildren();
		var segments 	= this.getSegments();
		var oldSegments = this.oldSegments;
		var _this       = this;
		
		if(children.getSize() === 0){
			return;
		}
		
		if(!oldSegments || !segments){
			return;
		}
		
		//线段数量没有变化仅仅发生了移动
		if(oldSegments.getSize() === segments.getSize()){
			children.each(function(i,figure){
				if(figure instanceof draw2d.shape.basic.Label){
					return true;
				}
				var oldSeg 		 = null;	//移动前的图元所在线段
				var newSeg 		 = null;	//移动后的图元所在线段
				var figLoc 		 = new draw2d.geo.Point(figure.x,figure.y);	//图元的当前位置
				var figOnLineLoc = new draw2d.geo.Point(figure.x-figure.width/2,figure.y-figure.height/2);//图元在线段上的位置
				
				//如果图元还没有关联线段，则搜索图元所在线段并为图元关联线段
		        var jointAttachedSegs = new draw2d.util.ArrayList();
		        var _jointAttachedSegs= figure.getAttachedSegments();
		        
		        _jointAttachedSegs.each(function(j,seg){
		        	jointAttachedSegs.add({start:seg.start,end:seg.end,index:seg.index});
		        });
		        
		        if(jointAttachedSegs.getSize() === 0){
		    	    segments.each(function(i,seg){
		    		   var start = seg.start;
		    		   var end   = seg.end;
		    		   seg.index = i;
		    		   if(start.x === (figure.x+figure.width/2) && start.y === (figure.y+figure.height/2)){
		    			   var _seg = {start:seg.start,end:seg.end,index:seg.index};
		    			   figure.addAttachedSegment(_seg);
		    		   }
		    		   if(end.x === (figure.x+figure.width/2) && end.y === (figure.y+figure.height/2)){
		    			   var _seg = {start:seg.start,end:seg.end,index:seg.index};
		    			   figure.addAttachedSegment(_seg);
		    		   }
		    	    });
		    	   
		    	    var hitSeg = _this.hitSegment(figure.x+figure.width/2,figure.y+figure.height/2);
		    	    if(hitSeg){
			    	    var _hitSeg = {start:hitSeg.start,end:hitSeg.end,index:hitSeg.index};
			    	    figure.addAttachedSegment(_hitSeg);
		    	    }
		       }else{
		    	   figure.clearAllAttachedSegment();
		    	   jointAttachedSegs.each(function(j,attached){
		    		   var _index = attached.index;
		    		   var size   = segments.getSize();
		    		   if (_index >= size) {
		    		   		_index = size -1;
		    		   }
		    		   var newSeg = segments.get(_index);
		    		   if(newSeg){
			    		   var _newSeg= {start:newSeg.start,end:newSeg.end,index:_index};
			    		   figure.addAttachedSegment(_newSeg);
		    		   }
		    	   });
		       }
			});
			
		}
					
		//有线段删除
		if(oldSegments.getSize() > segments.getSize()){
			console.log(">>");
		}
		
		//有线段增加
		if(oldSegments.getSize() < segments.getSize()){
			console.log("<<");
		}
		
		_this.children.each(function(i,e){
			if(e.figure instanceof Rainier.UI.V2.JointFigure && e.locator){
				e.locator.relocate(i, e.figure);				
			}
        });
		
	}
});